package trading_strategy.events.filtered;

import org.apache.log4j.Logger;
import trading_strategy.events.AbstractMarketEvent;
import trading_strategy.events.InstrumentEvent;
import trading_strategy.instruments.ListedInstrument;

import java.util.LinkedList;

/**
 * Arithmetic moving average based on a candle signal
 * Created by IntelliJ IDEA.
 * User: gderoujoux
 * Date: 6 mai 2010
 * Time: 12:05:58
 * To change this template use File | Settings | File Templates.
 */
public class AMMFilter extends DerivedSignal {
    public static final Logger LOGGER = Logger.getLogger(AMMFilter.class);

    public class AMMEvent extends InstrumentEvent {
        double value;
        AMMEvent(ListedInstrument instrument, double value, long ts) {
            super(instrument, ts);
            this.value = value;
        }
        public double getValue() {
            return value;
        }

    }

    LinkedList<Candle> candles = new LinkedList<Candle>();
    int nbOfIntervals = 28;
    CandleFilter candleFilter;

    public AMMFilter(ListedInstrument instrument, String name, int nbOfIntervals, CandleFilter candleFilter) {
        super(name, "FilteredSignalDispatcher", instrument, candleFilter);
        this.nbOfIntervals = nbOfIntervals;
        this.candleFilter = candleFilter;
    }

    @Override
    public void onMarketEvent(AbstractMarketEvent event) {
        if (event instanceof CandleFilter.CandleEvent) {
            CandleFilter.CandleEvent ce = (CandleFilter.CandleEvent) event;
            Candle candle = ce.getCandle();
            if (candles.size() >= nbOfIntervals) {
                Candle out = candles.pop();
            }
            // Check that there is no gap in the candles
            if (candles.size() > 0) {
                Candle last = candles.getLast();
                long gapMs = candle.getStart().getTime() - last.getEnd().getTime();
                long lastDuration = last.getEnd().getTime() - last.getStart().getTime();
                if (gapMs > lastDuration / 5) {
                    candles.clear();
                    LOGGER.warn("Gap in candle signal, resetting");
                    return;
                }
            }

            candles.add(candle);
            if (candles.size() >= nbOfIntervals / 2) {
                double average = 0;
                for (Candle c : candles) {
                    average += c.getClose();
                }
                average /= (double) candles.size();
                AMMEvent e = new AMMEvent(instrument, average, event.getTs());
                addEvent(e);
            }
        }
    }
}